package com.security.demo.custom;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import com.security.demo.model.Resource;
import com.security.demo.service.ResourceService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

	private boolean expire = false; // 过期标识

	@Autowired
	private ResourceService resourceService; // 资源服务类

	private Map<String, ConfigAttribute> kv = new HashMap<String, ConfigAttribute>(); // 资源集合

	public boolean supports(Class<?> clazz) {
		return true;
	}

	// 初始化方法时候从数据库中读取资源
	// @PostConstruct
	public void init() {
		load();
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		Set<ConfigAttribute> attributes = new HashSet<ConfigAttribute>();
		for (Map.Entry<String, ConfigAttribute> entry : kv.entrySet()) {
			attributes.add(entry.getValue());
		}
		return attributes;
	}

	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		FilterInvocation filterInvocation = (FilterInvocation) object;
		String url = filterInvocation.getRequestUrl();
		if (log.isDebugEnabled()) {
			log.debug("访问的URL地址为(包括参数):{}", url);
		}
		url = filterInvocation.getRequest().getServletPath();
		if (log.isDebugEnabled()) {
			log.debug("访问的URL地址为(除去参数):{}", url);
		}
		String permission = resourceService.findPermissionByUrl(url);
		if (StringUtils.isNotBlank(permission)) {
			Collection<ConfigAttribute> ret = new HashSet<ConfigAttribute>();
			ret.add(new SecurityConfig(permission));
			return ret;
		}
		return null;
	}

	/**
	 * 加载所有资源与权限的关系
	 */
	public void load() {
		List<Resource> resources = resourceService.findAll();
		for (Resource resource : resources) {
			kv.put(resource.getName(), new SecurityConfig(resource.getPermission()));
		}
	}

	public boolean isExpire() {
		return expire;
	}

	public void expireNow() {
		this.expire = true;
	}

}
